package com.imooc.config;

import org.apache.shiro.codec.Base64;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.mgt.SecurityManager;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

//@Configuration
public class ShiroRedisConfig {
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm());
        securityManager.setRememberMeManager(null);

        // 自定义缓存管理器 - redis
        RedisCacheManager cacheManager = new RedisCacheManager();
        cacheManager.setRedisManager(redisManager());
        securityManager.setCacheManager(cacheManager);

        // 自定义一个存储session的管理器
        securityManager.setSessionManager(sessionManager());

        return securityManager;
    }

    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        return myShiroRealm;
    }


    // 自定义session管理器
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();

        // shiro sessionDao层的实现，通过redis - 使用的是shiro-redis开源插件
        RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
        redisSessionDAO.setRedisManager(redisManager());

        // 设置存储在缓存中session的Key的前缀
        redisSessionDAO.setKeyPrefix("spring_shiro_redis_session:");
        sessionManager.setSessionDAO(redisSessionDAO);
        return sessionManager;
    }

    public RedisManager redisManager() {
        RedisManager redisManager = new RedisManager();
        redisManager.setHost("127.0.0.1");
        redisManager.setPort(6379);
        // 链接的超时
        redisManager.setTimeout(30);
        // 缓存key的超时
        redisManager.setExpire(20);
        return redisManager;
    }

    // 拦截url
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String,String> map = new LinkedHashMap<>();

        // anon--匿名访问 (访问静态文件)
        map.put("/assets/**","anon");
        map.put("/imgs/**","anon");
        map.put("/js/**","anon");
        map.put("/layer/**","anon");
        map.put("/ueditor/**","anon");
        map.put("/ztree/**","anon");

        // swagger相关
        map.put("/swagger-ui.html","anon");
        map.put("/swagger-resources/**","anon");
        map.put("/v2/api-docs","anon");
        map.put("/webjars/**","anon");

        map.put("/user/add", "anon");
        map.put("/user/uploadHeadImg", "anon");
        map.put("/user/queryUserInfo", "anon");

        map.put("/card/queryListByaPage", "anon");

        // 登录相关
        map.put("/checkLogin","anon");
        map.put("/login","anon");

        // authc - 认证后可访问
        // filterChainDefinitionMap.put("/**", "authc");
        // user - 记住我或登录可访问
        map.put("/**", "authc");

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setSuccessUrl("/");
        //未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
        /**
         当前登录用户: <shiro:principal/><br/>
         <shiro:authenticated>我已登录,但未记住<br/></shiro:authenticated>
         <shiro:user>我已登录,或已记住<br/></shiro:user>
         <shiro:guest>我是访客<br/></shiro:guest>
         <shiro:hasAnyRoles name="manager,admin">manager or admin 角色用户登录显示此内容<br/></shiro:hasAnyRoles>
         <shiro:hasRole name="系统管理员">我是系统管理员<br/></shiro:hasRole>
         <h2>权限列表</h2>
         <shiro:hasPermission name="权限列表">具有权限列表权限用户显示此内容<br/></shiro:hasPermission>
         <shiro:lacksPermission name="角色分配保存">不具有角色分配保存权限的用户显示此内容 <br/></shiro:lacksPermission>
         */
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}